package com.jsy.testlock.entity;

import com.jsy.testlock.lockimpl.FakeLock;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: SongyangJi
 * @description:
 * @since: 2021/11/29
 */
public class MyInteger {
    private int x;

    public MyInteger(int x) {
        this.x = x;
    }

    public void incr() {
        ++x;
    }

    public void decr() {
        --x;
    }

    public int getX() {
        return x;
    }

    public static void testLock(Lock lock) {
        System.out.println("test ... ");
        long l = System.currentTimeMillis();
        final int N = 10;
        MyInteger integer = new MyInteger(N);
        CountDownLatch countDownLatch = new CountDownLatch(N);
        ExecutorService pool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < N; i++) {
            pool.submit(() -> {
                lock.lock();
                try {
                    integer.decr();
                } finally {
                    lock.unlock();
                }
                countDownLatch.countDown();
            });
        }
        try {
            countDownLatch.await(); // just wait all tasks to finish
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("end : " + integer.getX());
        long r = System.currentTimeMillis();
        System.out.println("耗时 " + (r - l) + " ms");
    }

    public static void main(String[] args) {
        System.out.println("测试 FakeLock");
        testLock(new FakeLock());
        System.out.println("测试 ReentrantLock");
        testLock(new ReentrantLock());
    }
}
